package gateway.util;

import io.jsonwebtoken.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

public class AppJwtUtil {

    // TOKEN的有效期一天（MS）
    private static final int TOKEN_TIME_OUT = 3600 * 1000 * 24;
    // 加密KEY
    private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
    // 最小刷新间隔（S）
    private static final int REFRESH_TIME = 300;

    /**
     * 生成token
     * @param claimMaps  自定义信息
     * @return
     */
    public static String getToken(Map<String,Object> claimMaps){
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))     //签发时间
                .setSubject("system")   //说明
                .setIssuer("heima")   // 签发者信息
                .setAudience("app")   // 接收用户
                .compressWith(CompressionCodecs.GZIP)    // 数据压缩方式
                .signWith(SignatureAlgorithm.HS512,generalKey())  // 加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT))  // 过期时间戳
                .addClaims(claimMaps)  // cla信息
                .compact();
    }

    /**
     * 获取token中的claims信息
     * @param token
     */
    private static Jws<Claims> getJws(String token) {
        return Jwts.parser()
                .setSigningKey(generalKey())
                .parseClaimsJws(token);
    }

    /**
     * 获取payload body信息
     * @param token
     * @return
     */
    public static Claims getClaimsBody(String token) {
        try {
            return getJws(token).getBody();
        }catch (ExpiredJwtException e){
            return null;
        }
    }

    /**
     * 获取header body信息
     * @param token
     * @return
     */
    public static JwsHeader getHeaderBody(String token){
        return getJws(token).getHeader();
    }

    /**
     * 是否过期
     * @param claims
     * @return -1: 有效， 0：有效，1：过期，2：过期
     */
    public static int verifyToken(Claims claims) {
        if (claims == null){
            return 1;
        }
        try{
            claims.getExpiration()
                    .before(new Date());
            if ((claims.getExpiration().getTime() - System.currentTimeMillis()) > REFRESH_TIME * 1000){
                return -1;
            }else {
                return 0;
            }
        }catch (ExpiredJwtException ex){
            return 1;
        }catch (Exception e){
            return 2;
        }
    }

    /**
     * 由字符串生成加密key
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodeKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
        SecretKeySpec key = new SecretKeySpec(encodeKey, 0, encodeKey.length, "AES");
        return key;
    }

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("userId","10001");
        map.put("userName","tom");
        String token = AppJwtUtil.getToken(map);
        System.out.println(token);
        Jws<Claims> jws = AppJwtUtil.getJws(token);
        Claims claims = jws.getBody();
        System.out.println(claims.get("userId"));
        System.out.println(claims.get("userName"));
    }
}
